package pe.gob.foncodes.ssa.bs.common.service.impl;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.jstl.sql.Result;
import javax.servlet.jsp.jstl.sql.ResultSupport;

import org.apache.log4j.Logger;

import pe.gob.foncodes.ssa.bs.common.dao.GenericDao;
import pe.gob.foncodes.ssa.bs.common.dao.impl.GenericDaoJpa;
import pe.gob.foncodes.ssa.bs.common.service.GenericService;
import pe.gob.foncodes.ssa.bs.common.util.DaoException;
import pe.gob.foncodes.ssa.bs.common.util.ServiceException;

public class GenericServiceImpl implements GenericService {

    protected Logger log;
    private GenericDao genericDao;

    public GenericServiceImpl() {
        log = Logger.getLogger(getClass());
    }

    public void setGenericDAO(GenericDao GenericDao) {
        this.genericDao = GenericDao;
    }

    public GenericDao getDAO() {
        return genericDao;
    }

    @Override
    public Connection getConnection() throws Exception {
        try {
            if (this.genericDao == null) {
                this.genericDao = new GenericDaoJpa();
            }
            return getDAO().getConnection();
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Result getJstlResultFromQuery(String query) throws ServiceException {
        try {
            Connection connection = getDAO().getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet resultset = preparedStatement.executeQuery();
            //ResultSetDynaClass resultSetDyanaClass = new ResultSetDynaClass(resultset);
            Result result = ResultSupport.toResult(resultset);
            resultset.close();
            connection.close();
            return result;
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public void delete(Object persistentInstance) throws Exception, ServiceException, SQLException {
        try {
            getDAO().delete(persistentInstance);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public void deleteById(Class clazz, Serializable id)
            throws ServiceException {
        try {
            getDAO().deleteById(clazz, id);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public void delete(Collection collection) throws Exception {
        try {
            getDAO().delete(collection);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public boolean exists(Class clazz, String id) throws ServiceException {
        try {
            return getDAO().exists(clazz, id);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Object findById(Class clazz, Serializable id)
            throws ServiceException {
        try {
            return getDAO().findById(clazz, id);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Object findByCode(Class clazz, String cod) throws ServiceException {
        try {
            return getDAO().findByCode(clazz, cod);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Object findGeneralByCode(Class clazz, String cod) throws Exception {
        try {
            return getDAO().findGeneralByCode(clazz, cod);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }
    
    @Override
    public List findByObject(Object object) throws ServiceException {
        try {
            return getDAO().findByObject(object);
        } catch (DaoException e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Date getCurrentDate() throws ServiceException {
        try {
            return getDAO().getCurrentDate();
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public String getIdFieldName(Class clazz) throws ServiceException {
        try {
            return getDAO().getIdFieldName(clazz);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Object save(Object object) throws ServiceException {
        Object result = null;
        try {
            result = getDAO().save(object);
            //object = getDAO().save(object);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
        return result;
    }

    @Override
    public void persist(Object object) throws ServiceException {
        try {
            getDAO().persist(object);
            //object = getDAO().save(object);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }
    
    @Override
    public void saveCollection(Collection collection) throws ServiceException {
        try {
            getDAO().saveCollection(collection);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

//	public void saveCollectionAndProcessTask(Collection collection,
//			OrdenTaskExecutor ordenTaskExecutor, ParametroHelper parametroHelper,
//			ProvisionService provisionService, PuertoService puertoService, UsuarioDemo usuario) throws ServiceException{
//		try {
//			getDAO().saveCollectionAndProcessTask(collection, ordenTaskExecutor, parametroHelper, provisionService, puertoService, usuario);
//		} catch (Exception e) {
//			log.error(e);
//			throw new ServiceException(e);
//		}
//	}
    @Override
    public Object getReference(Class class1, Serializable serializable) throws ServiceException {
        Object clase = null;
        try {

            clase = getDAO().getReference(class1, serializable);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }

        return clase;
    }

    @Override
    public void refresh(Object object) throws ServiceException {
        try {
            getDAO().refresh(object);
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public void refreshCollection(Collection collection) throws ServiceException {
        try {
            for (Object object : collection) {
                getDAO().refresh(object);
            }
        } catch (Exception e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public void initialize(Object object) throws ServiceException {
        try {
            getDAO().initialize(object);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List findByNamedQuery(String queryName) throws ServiceException {
        try {
            return getDAO().findByNamedQuery(queryName);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List findByNamedQuery(String queryName, Object[] values) throws ServiceException {
        try {
            return getDAO().findByNamedQuery(queryName, values);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List findByNamedQuery(String queryName, Map<String, ?> params) throws ServiceException {
        try {
            return getDAO().findByNamedQuery(queryName, params);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public Object findByNamedQueryUniqueRow(String queryName, Object[] values) throws ServiceException {
        try {
            return getDAO().findByNamedQueryUniqueRow(queryName, values);
        } catch (DaoException e) {
            log.debug(e);
            throw new ServiceException(e);
        }
    }

    @Override
    public Integer executeUpdate(String queryName, Object[] values) throws ServiceException {
        try {
            return getDAO().executeUpdate(queryName, values);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List createNativeQuery(String queryName, Class clase) throws ServiceException {
        try {
            return getDAO().createNativeQuery(queryName, clase);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public Object createNativeQuery(String queryName) throws ServiceException {
        try {
            return getDAO().createNativeQuery(queryName);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List createNativeQuery(String queryName, Object[] values) throws ServiceException {
        try {
            return getDAO().createNativeQuery(queryName,values);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }
    
    @Override
    public List find(String queryName) throws ServiceException {
        try {
            return getDAO().find(queryName);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List findByObjectDif(String clase, String campo, String valor, Long idObj) throws ServiceException {
        try {
            return getDAO().findByObjectDif(clase, campo, valor, idObj);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }
    
    @Override
    public boolean actualizaEnCascada(Long id, String flgActivo, String nombreProcedure) throws ServiceException, Exception{
        try {
            return getDAO().actualizaEnCascada(id, flgActivo, nombreProcedure);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public boolean agregaEnCascada(Long idOpcion, Long idAccion, Long idCtrlWeb, String flgActivo, String nombreProcedure) throws ServiceException, Exception{
        try {
            return getDAO().agregaEnCascada(idOpcion, idAccion, idCtrlWeb, flgActivo, nombreProcedure);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }
    
    @Override
    public List<Long> getModulosHijos(Long nidModulo) throws ServiceException {
        try {
            return getDAO().getModulosHijos(nidModulo);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }
    
    @Override
    public boolean validaExistenciaEnPerfilOAutorizacion(Long nid, Long nidOpcion, String sTipo) throws ServiceException {
        try {
            return getDAO().validaExistenciaEnPerfilOAutorizacion(nid, nidOpcion, sTipo);
        } catch (DaoException e) {
            log.error(e);
            throw new ServiceException(e);
        }
    }
    
    @Override
    public List<Object[]> reporteOpcionxModulo(Long nidModulo, Long nidPerfil, String codUsuario) throws ServiceException, Exception
    {
        try {
            return getDAO().reporteOpcionxModulo(nidModulo, nidPerfil, codUsuario);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public boolean actualizaPerfilOpcionEnCascada(Long idPerfil, Long idOpcion, String flgConsulta, String flgActivo, Long idCtrlWeb, String nombreProcedure) throws ServiceException, Exception{
        try {
            return getDAO().actualizaPerfilOpcionEnCascada(idPerfil, idOpcion, flgConsulta, flgActivo, idCtrlWeb, nombreProcedure);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }
    
}